from copy import deepcopy
from multiprocessing import Value

from rest_framework import serializers

from jqgame.basegame import GameType
from jqpackage.models import UserPackageGoods, UserPackageGoodsState
from warehouse.models import JuqiGood, GoodLevel, GoodLevelGameType
from warehouse.serializers import JuqiGoodSerializer
from wuxianshang.models import WuxianshangRaffleRecord, WuxianshangGameGood
from wxcloudrun.ser import BaseSerializer
from .models import (
    UserHunJingRecord,
    UserScoreRecord,
    Users,
    UserStoredMoneyRecord,
    UserPackage,
    UserPackageRecord,
    UserRechargeOrder,
    UserOrder,
    UserRefinedOrder,
    UserRefinedOrderGoods,
)


class UserSerializer(BaseSerializer):
    class Meta:
        model = Users
        fields = "__all__"


class UserResultSerializer(BaseSerializer):
    inviter_name = serializers.SerializerMethodField()

    # shangdai_shangpin_jiazhi = serializers.SerializerMethodField()

    def get_inviter_name(self, obj):
        if obj.inviter_uuid is None:
            return
        return UserSerializer(
            instance=Users.objects.filter(deleted=False)
            .filter(uuid=obj.inviter_uuid)
            .first()
        ).data.get("nickname")

    class Meta:
        model = Users
        fields = [
            "id",
            "uuid",
            "nickname",
            "head_url",
            "stored_money",
            "package_amount",
            "hunjing",
            "score",
            "inviter_name",
            "lv",
            "telephone",
            "is_daili",
            "is_real",
            "state",
            "createdAt",
            "need_help",
        ]


class UserStoredMoneyRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserStoredMoneyRecord
        fields = "__all__"


class UserHunJingRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserHunJingRecord
        fields = "__all__"


class UserScoreRecordSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserScoreRecord
        fields = "__all__"


class UserPackageSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserPackage
        fields = "__all__"


class UserPackageRecordSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserPackageRecord
        fields = "__all__"


class UserRechargeOrderSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserRechargeOrder
        fields = "__all__"


_game_type_name = {
    GameType.wuxianshang: "无限赏",
    GameType.wuxianshang_boss: "无限赏-boss赏",
    GameType.quanjushang: "全局赏",
    GameType.yifanshang: "一番赏",
}


def get_game_name(game_type):
    """
    获取游戏类型的中文名称
    Args:
        game_type: 游戏类型

    Returns: 中文名称

    """
    return _game_type_name[game_type]


class UserOrderSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    game_type_name = serializers.SerializerMethodField()

    def get_game_type_name(self, obj):
        game_type = obj.game_type
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))

    class Meta:
        model = UserOrder
        fields = "__all__"


class UserRecordRefinedGoodsVSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    display_url = serializers.CharField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    recovery_price = serializers.IntegerField(read_only=True)
    sum_count = serializers.IntegerField(read_only=True)
    game_type = serializers.CharField(read_only=True)
    level_title = serializers.CharField(read_only=True)


class UserRecordRefinedGoodsV2Serializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    display_url = serializers.CharField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    recovery_price = serializers.IntegerField(read_only=True)
    sum_count = serializers.IntegerField(read_only=True)
    game_type = serializers.CharField(read_only=True)
    level_title = serializers.CharField(read_only=True)
    sum_price = (serializers.IntegerField(read_only=True),)
    sum_recovery_price = serializers.IntegerField(read_only=True)


class UserHistoryRefiningSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    goods = serializers.SerializerMethodField()

    def get_goods(self, obj):
        _query_set = (
            UserRefinedOrderGoods.objects.filter(deleted=False)
            .filter(order_refined_uuid=obj.uuid)
            .extra(
                select={
                    "name": "JuqiGood.name",
                    "display_url": "JuqiGood.display_url",
                    "price": "JuqiGood.price",
                    "recovery_price": "JuqiGood.recovery_price",
                    "game_type": "JuqiGood.game_type",
                    "level_title": "JuqiGood.level_title",
                },
                tables=["JuqiGood"],
                where=["JuqiGood.uuid=UserRefinedOrderGoods.good_uuid"],
            )
        )
        _query_set = _query_set.values(
            "name",
            "display_url",
            "price",
            "recovery_price",
            "game_type",
            "createdAt",
            "level_title",
            "good_uuid",
        )
        _query_set = _query_set.order_by("-recovery_price").all()
        _list = []
        refined_goods_dict = dict()
        for refined_goods in _query_set:
            _get_refined_goods = refined_goods_dict.get(refined_goods["good_uuid"])
            if _get_refined_goods is None:
                refined_goods_dict[refined_goods["good_uuid"]] = {
                    "name": refined_goods["name"],
                    "display_url": refined_goods["display_url"],
                    "price": refined_goods["price"],
                    "recovery_price": refined_goods["recovery_price"],
                    "game_type": refined_goods["game_type"],
                    "createdAt": refined_goods["createdAt"],
                    "level_title": refined_goods["level_title"],
                    "good_uuid": refined_goods["good_uuid"],
                    "sum_price": 0,
                    "sum_recovery_price": 0,
                    "sum_count": 0,
                }
            _refined_goods_cru = refined_goods_dict[refined_goods["good_uuid"]]
            _refined_goods_cru["sum_price"] += refined_goods["price"]
            _refined_goods_cru["sum_recovery_price"] += refined_goods["recovery_price"]
            _refined_goods_cru["sum_count"] += 1
        refined_goods_list = list(refined_goods_dict.values())
        for refined_goods in refined_goods_list:
            _refined_goods = UserRecordRefinedGoodsV2Serializer(refined_goods).data
            _list.append(_refined_goods)
        return _list

    class Meta:
        model = UserRefinedOrder
        fields = "__all__"


# def save_UserPackages(infos, game_type: GameType, game):
#     ups_update = []
#     ups_create = []
#     uprs_create = []
#     wxsrrs_create = []
#
#     current_raffle_count: int = 0
#     if game_type == GameType.wuxianshang:
#         current_raffle_count = game.count
#
#     elif game_type == GameType.wuxianshang_boss:
#         current_raffle_count = game.history_times
#
#     def _save_UserPackage(user: Users, good: JuqiGood, count: int):
#         nonlocal current_raffle_count
#
#         info = {"user_uuid": user.uuid, "good_uuid": good.uuid, "deleted": False}
#         UserPackage.objects.select_for_update()
#         if UserPackage.objects.filter(**info).exists():
#             up = UserPackage.objects.get(**info)
#             up.count += count
#             ups_update.append(up)
#         else:
#             info["count"] = count
#             ups_create.append(UserPackage(**info))
#
#         info["count"] = count
#         info["detail"] = f"获得 {good.name}: {count} 个"
#
#         uprs_create.append(UserPackageRecord(**info))
#
#         del info["detail"]
#
#         for v in range(count):
#             info["game_uuid"] = game.uuid
#             info["count"] = 1
#             current_raffle_count += 1
#             info["raffle_count"] = current_raffle_count
#             if game_type == GameType.wuxianshang:
#                 wxsrrs_create.append(WuxianshangRaffleRecord(**info))
#             elif game_type == GameType.wuxianshang_boss:
#                 info["extend_type_boss"] = True
#                 info["boss_history_times"] = game.history_times
#                 wxsrrs_create.append(WuxianshangRaffleRecord(**info))
#
#     for i in infos:
#         _save_UserPackage(*i)
#
#     UserPackage.objects.bulk_update(ups_update, ["count"], batch_size=1000)
#     UserPackage.objects.bulk_create(ups_create, batch_size=1000)
#     UserPackageRecord.objects.bulk_create(uprs_create, batch_size=1000)
#
#     if (game_type == GameType.wuxianshang) or (game_type == GameType.wuxianshang_boss):
#         WuxianshangRaffleRecord.objects.bulk_create(wxsrrs_create, batch_size=1000)


def save_UserPackages(
    good_uuid_list, game_type: GameType, game, user_obj, user_order_uuid
):
    current_raffle_count: int = 1
    if game_type == GameType.wuxianshang:
        current_raffle_count = game.count + 1

    ups_create = []
    wxsrrs_create = []

    now_k = ""
    good_type = 0
    level_title = ""
    for good_uuid in good_uuid_list:
        if now_k != good_uuid:
            now_k = good_uuid
            game_good_obj = (
                WuxianshangGameGood.objects.filter(game_uuid=game.uuid)
                .filter(good_uuid=good_uuid)
                .first()
            )
            good_level_obj = (
                GoodLevel.objects.filter(game_type=GoodLevelGameType.wuxianshang.value)
                .filter(uuid=game_good_obj.level_uuid)
                .first()
            )
            good_type = game_good_obj.good_type
            level_title = good_level_obj.title

        info = {
            "user_uuid": user_obj.uuid,
            "good_uuid": good_uuid,
            "good_level_title": level_title,
            "game_type": game_type.value,
            "game_uuid": game.uuid,
            "order_num": current_raffle_count,
            "order_uuid": user_order_uuid,
        }

        if good_type == 0:
            rr_info = {
                "user_uuid": user_obj.uuid,
                "game_uuid": game.uuid,
                "good_uuid": good_uuid,
                "count": 1,
                "raffle_count": current_raffle_count,
            }

            current_raffle_count += 1
        else:
            rr_info = {
                "user_uuid": user_obj.uuid,
                "game_uuid": game.uuid,
                "good_uuid": good_uuid,
                "count": 1,
                "raffle_count": 0,
            }

        ups_create.append(UserPackageGoods(**info))
        wxsrrs_create.append(WuxianshangRaffleRecord(**rr_info))
    UserPackageGoods.objects.bulk_create(ups_create, batch_size=1000)
    WuxianshangRaffleRecord.objects.bulk_create(wxsrrs_create, batch_size=1000)


def get_detail_UserPackage(user: Users):
    ups = (
        UserPackageGoods.objects.filter(user_uuid=user.uuid)
        .filter(state__in=[UserPackageGoodsState.unhandled, UserPackageGoodsState.lock])
        .filter(deleted=False)
        .all()
    )
    _goods = []
    for up in ups:
        g = JuqiGood.objects.filter(uuid=up.good_uuid).get(deleted=False)
        _g = JuqiGoodSerializer(g)
        _g_info = deepcopy(_g.data)
        _g_info["count"] = up.count
        _goods.append(_g_info)
    return _goods


def calculate_UserPackage_sum_price_by_date(user_uuid, sum_date):
    if sum_date is None:
        raise ValueError
    ups = (
        UserPackageGoods.objects.filter(deleted=False)
        .filter(user_uuid=user_uuid)
        .filter(state__in=[UserPackageGoodsState.unhandled, UserPackageGoodsState.lock])
        .filter(createdAt__year=sum_date.year)
        .filter(createdAt__month=sum_date.month)
        .filter(createdAt__day=sum_date.day)
        .all()
    )
    sum_recovery_price = 0
    for up in ups:
        g = JuqiGood.objects.filter(uuid=up.good_uuid).filter(deleted=False).first()
        if g is None:
            break
        sum_recovery_price += g.recovery_price
    return sum_recovery_price


class GameListSerializer(serializers.Serializer):
    uuid = serializers.UUIDField(read_only=True)
    name = serializers.StringRelatedField(read_only=True)
    cover_url = serializers.StringRelatedField(read_only=True)
    game_type = serializers.IntegerField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    is_care = serializers.IntegerField(read_only=True)
    is_ccs = serializers.IntegerField(read_only=True)
    is_fjf = serializers.IntegerField(read_only=True)
    score_pay = serializers.IntegerField(read_only=True)
    baodi = serializers.IntegerField(read_only=True)
    tianjiangsb = serializers.IntegerField(read_only=True)
    feiqiu = serializers.IntegerField(read_only=True)
    feiqiu_num = serializers.IntegerField(read_only=True)
    # "is_care","is_ccs","is_fjf","score_pay"
